using System;
using System.Collections.Generic;
using System.Collections.Specialized;
using System.ComponentModel;
using System.Data;
using System.Security;
using System.Text;
using System.Web;
using System.Web.UI;
using System.Web.UI.WebControls;
using System.Web.UI.WebControls.WebParts;
using System.Xml.Serialization;

using Microsoft.SharePoint;
using Microsoft.SharePoint.WebControls;
using Microsoft.SharePoint.WebPartPages;

namespace CoolStuffs.Sharepoint.Webparts.RecentItems
{
    /// <summary>
    /// Example of how can the base webpart be used
    /// for universal content aggregator
    /// </summary>
    public class UniversalAggregator : BaseContentAggregator
    {

        #region Nested Enums/Structures/Classes

        #region Public
        #endregion

        #region Protected
        #endregion

        #region Private
        #endregion

        #region Internal
        #endregion

        #endregion

        #region Member Variables

        #region Public
        #endregion

        #region Protected
        #endregion

        #region Private
        private DataTable _recentItemsDataTable;
        private const System.String _fileRef = "FileRef";
        private const System.String _fileLeafRef = "FileLeafRef";
        private const System.String _name = "Name";
        private const System.String _title = "Title";
        private const System.String _oneInTheEnd = "1";
        private const System.String _slash = "/";
        #endregion

        #region Internal
        #endregion

        #endregion

        #region Constructors/Destructors

        #region Public
        /// <summary>
        /// Default constructor
        /// </summary>
        public UniversalAggregator()
            : base()
        {

        }
        #endregion

        #region Protected
        #endregion

        #region Private
        #endregion

        #region Internal
        #endregion

        #endregion

        #region Properties

        #region Public
        /// <summary>
        /// For showing recent Items across all content types,
        /// we would need to give the end user, the option to choose the
        /// base type of the lists he need to see the 
        /// recent Items of
        /// </summary>
        [WebBrowsable(true)]
        [Personalizable(true)]
        [Category("Presentation")]
        [WebPartStorage(Storage.Personal)]
        [FriendlyNameAttribute("Select Base Content Type")]
        [XmlElement(ElementName = "ListBaseType")]
        public DocumentBaseTypeScope BaseListContentType
        {
            get
            {
                return this.DocumentTypeBase;
            }
            set
            {
                this.DocumentTypeBase = value;
            }
        }
        #endregion

        #region Protected
        #endregion

        #region Private
        #endregion

        #region Internal
        #endregion

        #endregion

        #region Methods

        #region Public
        #endregion

        #region Protected
        /// <summary>
        /// CreateChildControls Event of System.Web.UI.WebControls.Webparts.Webpart
        /// </summary>
        protected override void CreateChildControls()
        {
            base.CreateChildControls();
            this.ContentTypeSpecificAction();
            string[] _fields;
            switch (this.BaseListContentType)
            {
                case DocumentBaseTypeScope.DocumentLibrary:
                    _fields = new string[1] { _fileRef };
                    this.InsertItemNameFieldInGrid(_fields, _fileLeafRef, _name);
                    break;
                case DocumentBaseTypeScope.GenericList:
                    // IMPORTANT : 'Link' and 'Languages and translators' list
                    // dont have Title column, Items from these list wont have
                    // any display name, you'll need to get the data from the required
                    // column that you think is the Display Name column for these 
                    // list in the title column in the this._dtRecentItemsDataTable
                    // before telling the Hyperlink field that it has to point to
                    // title column to get the display name
                    _fields = new string[1] { this.ItemDisplayFormUrlField };
                    this.InsertItemNameFieldInGrid(_fields, _title, _name);
                    break;
                case DocumentBaseTypeScope.DiscussionForum:
                    // TODO:
                    break;
                case DocumentBaseTypeScope.IssueList:
                    // TODO:
                    break;
                case DocumentBaseTypeScope.Survey:
                    // TODO:
                    break;
            }
            this.BindGrid();
        }

        /// <summary>
        /// This is a Overriden Method of
        /// the base class
        /// </summary>
        protected override void ContentTypeSpecificAction()
        {
            DataTable _tempTable;
            switch (this.BaseListContentType)
            {
                /// Add Content Type specific columns in FieldsInDocumentType dictionary
                /// and do other Base type specific plumbing neccesary
                case DocumentBaseTypeScope.DocumentLibrary:
                    {
                        this.FieldsInDocumentType[this.BaseListContentType].Add(_fileRef);
                        this.FieldsInDocumentType[this.BaseListContentType].Add(_fileLeafRef);
                        this.GetRecentItemsDataView(_fileRef);
                        _tempTable = new DataTable();
                        this._recentItemsDataTable = this.RecentItemsDataView.ToTable();
                        _tempTable = this.RecentItemsDataView.ToTable();
                        /// You'll Find certain version trackers and hidden items
                        /// related to some internal tracking in Document
                        /// base type, which we dont need
                        this._recentItemsDataTable = _tempTable.Clone();
                        this._recentItemsDataTable.Clear();
                        foreach (DataRow row in _tempTable.Rows)
                        {
                            bool _unwantedHiddenItems = false;
                            string _row = row[_fileLeafRef].ToString();
                            string _annoyingOneBitItem = _row.Substring(_row.IndexOf(this.Hash) + 1);
                            _unwantedHiddenItems = _annoyingOneBitItem.EndsWith(_oneInTheEnd);
                            if (!_unwantedHiddenItems)
                            {
                                _recentItemsDataTable.Rows.Add(row.ItemArray);
                            }
                        }
                        /// tailoring column data for our need to get Document Name
                        /// as well as its fully qualified URL
                        foreach (DataRow _currentRow in _recentItemsDataTable.Rows)
                        {
                            string _fileLeafRefData = _currentRow[_fileLeafRef].ToString();
                            _currentRow[_fileLeafRef] = _fileLeafRefData.
                                Substring(_fileLeafRefData.IndexOf(this.Hash) + 1);
                            _fileLeafRefData = _currentRow[_fileLeafRef].ToString();
                            _currentRow[_fileRef] = _fileLeafRefData.
                                Substring(_fileLeafRefData.IndexOf(this.Hash) + 1);
                            _currentRow[_fileRef] = Page.Request.Url.GetLeftPart(UriPartial.Authority) +
                                _slash + _currentRow[_fileRef];
                            _currentRow.AcceptChanges();
                        }
                        /// finally, get the updated changes back in our final view
                        this.RecentItemsDataView = new DataView(this._recentItemsDataTable);
                        break;
                    }
                case DocumentBaseTypeScope.GenericList:
                    this.FieldsInDocumentType[this.BaseListContentType].Add(_title);
                    /// add extra fields you think you'll Need
                    this.GetRecentItemsDataView(_title);
                    _tempTable = new DataTable();
                    this._recentItemsDataTable = this.RecentItemsDataView.ToTable();
                    _tempTable = this.RecentItemsDataView.ToTable();
                    /// Most of the Generic List has the 'Title' field 
                    /// as the Item's display Name
                    /// though this is not the case with all of List
                    /// e.g.: 'Link' and 'Languages and translators' dont have Title
                    /// column. You need to take care of that before binding the
                    /// this.RecentItemsDataView to the grid
                    // TODO : perform other action nccesary you feel in Generic List
                    // Content type
                    /// finally, get the updated changes back in our final view
                    this.RecentItemsDataView = new DataView(this._recentItemsDataTable);
                    break;
                case DocumentBaseTypeScope.DiscussionForum:
                    //TODO:
                    break;
                case DocumentBaseTypeScope.IssueList:
                    //TODO:
                    break;
                case DocumentBaseTypeScope.Survey:
                    //TODO:
                    break;
            }
        }
        #endregion

        #region Private
        #endregion

        #region Internal
        #endregion

        #endregion
    }
}
